package design.pattern.singleton.seriable;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * @description:
 * @author: liuzhangcheng
 **/
public class SeriableSingletonTest {
    public static void main(String[] args) {
        // 测试SeriableSingleton 有没有重写 readResolve带来的影响

        SeriableSingleton s1 = SeriableSingleton.getInstance();
        SeriableSingleton s2 = null;

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("SeriableSingleton.obj");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(s1);
            oos.flush();
            oos.close();

            FileInputStream fis = new FileInputStream("SeriableSingleton.obj");
            ObjectInputStream ois = new ObjectInputStream(fis);
            // 步骤1：
            //  java.io.ObjectInputStream.readObject() -> readObject0()
            //  -> case TC_OBJECT -> readOrdinaryObject(unshared)
            // 步骤2
            //  -> obj = desc.isInstantiable() ? desc.newInstance() : null;
            //  desc.isInstantiable() -> return (cons != null); 说明对象只要有无参构造方法就会实例化
            // 步骤3
            //  无参构造方法存在时，readOrdinaryObject方法里又调用了desc.hasReadResolveMethod() (1808行) -> return (readResolveMethod != null);
            //      对 readResolveMethod的说明
            //          /** class-defined readResolve method, or null if none */
            //          private Method readResolveMethod;
            //  readResolveMethod在赋值呢？
            // 步骤4
            //  为readResolveMethod赋值
            //      java.id.ObjectStreamClass 1104 行:return readResolveMethod.invoke(obj, (Object[]) null);
            //  那有在哪调用了readResolveMethod方法了？ObjectInputStream 1810行
            //      Object rep = desc.invokeReadResolve(obj); -> invokeReadResolve方法里进行了调用
            //      java.id.ObjectStreamClass 506、507行 :readResolveMethod = getInheritableMethod(cl, "readResolve", null, Object.class);
            s2 = (SeriableSingleton) ois.readObject();
            ois.close();

            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s1 == s2);

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}
